const CDP = require('chrome-remote-interface'),
    log = require('../../util/log'),
    ocrMng = require('../../mng/ocrMng'),
    chromeMng = require('../chromeMng'),
    logger = require('log4js').getLogger(),
    config = require('../../util/config')

var lastLoginTaobaoTime = 0

var ChromeMng = function (obj) {
    obj = obj || {}
    this.port = obj.port;
    this.host = obj.host || '127.0.0.1'
    this.target = obj.target
    this.type = obj.type || ''
    this.busy = false
    this.isLoadEventFired = false
    this.resolve = obj.resolve || (() => { })
    this.reject = obj.reject || (() => { })
    this.store = obj.store || (() => { })
    this.port && this.connect()
    this.logOnce = true
    if (this.type == 'taobao') {
        this.username = obj.username || 'jun_1222'
        this.password = obj.password || 'yoyo@9876'
        this.store({
            username: this.username
        })
    }
}

ChromeMng.prototype.connect = function () {
    CDP({
        port: this.port,
        host: this.host,
        target: this.target
    }).then(client => {
        client.on('error', err => {
            logger.error('[' + __filename + ':' + __line + ']', this.host + ':' + this.port, err)

            var platform = require('os').platform()
            if (platform == 'linux') {
                // require('child_process').exec('docker run -d --privileged -p ' + port + ':9222 --rm justinribeiro/chrome-headless')
            } else if (platform == 'win32') {
                // var cmd = 'C:\\Users\\ye\\AppData\\Local\\Google\\Chrome\\Application\\chrome.exe --user-data-dir=d:\\chromeDevUserData1 --disable-web-security --remote-debugging-port=' + this.port
                // var cmd = 'C:\\Users\\zoro\\AppData\\Local\\Google\\Chrome\\Application\\chrome.exe --user-data-dir=d:\\chromeDevUserData1 --disable-web-security --remote-debugging-port=' + this.port
                // log(cmd)
                // require('child_process').exec(cmd)
            } else {
                logger.error('[' + __filename + ':' + __line + ']', platform)
            }
        })
        client.on('close', () => {
            logger.error('[' + __filename + ':' + __line + ']', this.host + ':' + this.port, 'on close')
            setTimeout(() => {
                this.connect()
            }, config.chromeReconnectTimeout)
        })

        this.logOnce = true
        if (this.type == 'taobao') {
            taobaoResolve.call(this, client)
        } else if (this.type == 'cgs') {
            cgsResolve.call(this, client)
        } else if (this.type == 'wechat') {
            wechatResolve.call(this, client)
        } else if (this.type == 'jd') {
            jdResolve.call(this, client)
        } else {
            resolve.call(this, client)
        }
    }).catch(err => {
        if (this.logOnce) {
            logger.error('[' + __filename + ':' + __line + ']', this.host + ':' + this.port, err)
            this.logOnce = false
        }
        setTimeout(() => {
            this.connect()
        }, config.chromeReconnectTimeout)
    })
}
ChromeMng.prototype.getTaobaoKeyWords = require('./getTaobaoKeyWords');
ChromeMng.prototype.getTaobaoItems = require('./getTaobaoItems');
ChromeMng.prototype.loginTaobao = require('./loginTaobao');
ChromeMng.prototype.getTaobaoAdvLink = require('./getTaobaoAdvLink');
ChromeMng.prototype.checkLoginTaobao = require('./checkLoginTaobao');
ChromeMng.prototype.loginJd = require('./loginJd');
ChromeMng.prototype.getJdAdvLink = require('./getJdAdvLink');
ChromeMng.prototype.getJdItems = require('./getJdItems');
ChromeMng.prototype.checkLoginJd = require('./checkLoginJd');
ChromeMng.prototype.getRedirectLink = require('./getRedirectLink');
ChromeMng.prototype.sendWechatMsg = require('./sendWechatMsg');
ChromeMng.prototype.loginWechat = require('./loginWechat');

// 无用了，填图形验证码
async function getAdvLink2Step3(client, code) {
    log('getting advertising link 2 step 3', code)
    const {
        Network,
        Page,
        DOM,
        Runtime,
        Emulation
    } = client;
    var {
        result
    } = await Runtime.evaluate({
        expression: 'document.querySelectorAll(".getcode-box textarea")'
    })
    var cnt = result.description.substring(9, result.description.length - 1)
    if (cnt != 0) {
        var {
            result
        } = await Runtime.evaluate({
            expression: 'document.querySelectorAll(".getcode-box textarea")[0].value'
        })
        return new Promise(resolve => {
            resolve(result.value)
            Runtime.evaluate({
                expression: 'document.querySelectorAll(".dialog-ext-close")[0].click()'
            })
        })
    }
    var {
        result
    } = await Runtime.evaluate({
        expression: 'document.querySelectorAll("#sufei-dialog-content")'
    })
    var cnt = result.description.substring(9, result.description.length - 1)
    if (cnt == 0) {
        return new Promise((resolve, reject) => {
            setTimeout(() => {
                resolve(getAdvLink2Step3(client, code))
            }, 1000)
        })
    }
    var {
        result
    } = await Runtime.evaluate({
        expression: 'document.querySelectorAll("#sufei-dialog-content")[0].contentDocument.querySelectorAll("#J_CodeInput")'
    })
    var cnt = result.description.substring(9, result.description.length - 1)
    if (cnt == 0) {
        return new Promise((resolve, reject) => {
            setTimeout(() => {
                resolve(getAdvLink2Step3(client, code))
            }, 1000)
        })
    }
    await Runtime.evaluate({
        expression: 'document.querySelectorAll("#sufei-dialog-content")[0].contentDocument.querySelectorAll("#J_CodeInput")[0].value="' + code + '"'
    })
    await Runtime.evaluate({
        expression: 'document.querySelectorAll("#sufei-dialog-content")[0].contentDocument.querySelectorAll("#J_submit")[0].click()'
    })
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve(getAdvLink2Step3(client, code))
        }, 1000)
    })
}

async function screenshot(client) {
    log('screenshotting')
    const {
        Network,
        Page,
        DOM,
        Runtime,
        Emulation
    } = client;
    var result = await DOM.getDocument();
    var rootNodeId = result.root.nodeId
    const {
        nodeId: bodyNodeId
    } = await DOM.querySelector({
        selector: 'body',
        nodeId: rootNodeId,
    });
    const {
        model: {
            height
        }
    } = await DOM.getBoxModel({
        nodeId: bodyNodeId
    });
    await Emulation.setVisibleSize({
        width: 1440,
        height: height
    });
    const screenshot = await Page.captureScreenshot({
        format: 'png'
    });
    // const buffer = new Buffer(screenshot.data, 'base64');
    // return new Promise(resolve => {
    //   var filename = 'C:\\Users\\Administrator\\Desktop\\output\\' + parseInt(1000 * Math.random()) + '.png'
    //   require('fs').writeFile(filename, buffer, 'base64', err => {
    //     if (err) {
    //       log(err);
    //     }
    //     resolve(filename)
    //   });
    // })
    this.screenshot = screenshot.data
    setTimeout(() => {
        screenshot(client)
    }, 60000)
}

function resolve(client) {
    const {
        Network,
        Page,
        DOM,
        Runtime,
        Emulation
    } = client
    Page.loadEventFired(async () => { })
    Promise.all([Network.enable(), Page.enable(), DOM.enable()]).then(async () => {
        logger.debug('[' + __filename + ':' + __line + ']', 'chrome[' + this.host + ':' + this.port + '] connected')
        this.client = client
        this.resolve()
    }).catch(err => {
        logger.error('[' + __filename + ':' + __line + ']', error)
        client.close()
    })
}

function taobaoResolve(client) {
    const {
        Network,
        Page,
        DOM,
        Runtime,
        Emulation
    } = client;
    var qrcodeRequestId
    var taobaoBillRequestId
    var taobaoCodeRequestId
    Network.requestWillBeSent(obj => {
        if (obj.request.url.indexOf('://img.alicdn.com/tfscom/') != -1) {
            qrcodeRequestId = obj.requestId
        } else if (obj.request.url.indexOf('https://pub.alimama.com/openapi/param2/1/gateway.unionpub/report.getTbkOrderDetails.json') != -1) {
            // logger.info('[' + __filename + ':' + __line + ']', obj.requestId)
            taobaoBillRequestId = obj.requestId
        } else if (obj.request.url.indexOf('//pin.aliyun.com/get_img') != -1) {
            taobaoCodeRequestId = obj.requestId
        }
    });
    Network.loadingFinished(async obj => {
        if (obj.requestId == qrcodeRequestId) {
            var result = await Network.getResponseBody({
                requestId: obj.requestId
            })
            //var filename = '/tmp/qrcode.png'
            //require('fs').writeFile(filename, new Buffer(result.body, 'base64'), 'base64', async err => {
            //    if (err) {
            //        log(err);
            //        return
            //    }
            //})
            this.store({ qrcode: result.body })
            logger.debug('[' + __filename + ':' + __line + ']', '请扫二维码')
            if (new Date().getTime() - lastLoginTaobaoTime > 1800000) {
                logger.debug('[' + __filename + ':' + __line + ']', 'start login timeout')
                lastLoginTaobaoTime = new Date().getTime() + 10000
                setTimeout(async () => {
                    logger.debug('[' + __filename + ':' + __line + ']', 'trigger login timeout')
                    var { result } = await Runtime.evaluate({ expression: 'document.querySelectorAll("iframe[name=taobaoLoginIfr]")[0].contentDocument.querySelectorAll("#TPL_username_1")' })
                    //logger.debug('[' + __filename + ':' + __line + ']', result)
                    var cnt = result.description.substring(9, result.description.length - 1)
                    if (cnt == 1) {
                        var { result } = await Runtime.evaluate({ expression: 'document.querySelectorAll("iframe[name=taobaoLoginIfr]")[0].contentDocument.querySelectorAll("#TPL_password_1")' })
                        //logger.debug('[' + __filename + ':' + __line + ']', result)
                        var cnt = result.description.substring(9, result.description.length - 1)
                        if (cnt == 1) {
                            var { result } = await Runtime.evaluate({ expression: 'document.querySelectorAll("iframe[name=taobaoLoginIfr]")[0].contentDocument.querySelectorAll("#J_SubmitStatic")' })
                            //logger.debug('[' + __filename + ':' + __line + ']', result)
                            var cnt = result.description.substring(9, result.description.length - 1)
                            if (cnt == 1) {
                                await Runtime.evaluate({ expression: 'document.querySelectorAll("iframe[name=taobaoLoginIfr]")[0].contentDocument.querySelectorAll("#TPL_username_1")[0].value="' + this.username + '"' })
                                await Runtime.evaluate({ expression: 'document.querySelectorAll("iframe[name=taobaoLoginIfr]")[0].contentDocument.querySelectorAll("#TPL_password_1")[0].value="' + this.password + '"' })
                                await Runtime.evaluate({ expression: 'document.querySelectorAll("iframe[name=taobaoLoginIfr]")[0].contentDocument.querySelectorAll("#J_SubmitStatic")[0].click()' })
                            }
                        }
                    }
                }, 10000)
            }
        } else if (obj.requestId == taobaoBillRequestId) {
            var result = await Network.getResponseBody({
                requestId: obj.requestId
            })
            result = JSON.parse(result.body)
            if (!result.data) {
                logger.error('[' + __filename + ':' + __line + ']', JSON.stringify(result))
                if (result.info && result.info.message)
                    this.getTaobaoBillReject(result.info.message)
                else
                    this.getTaobaoBillReject()
                return
            }
            var data = result.data
            var { result } = await Runtime.evaluate({
                expression: 'location.href'
            })
            if (result.value.indexOf('queryType=2') != -1) {
                data.result.forEach(item => {
                    if (item.tkStatus != 3)
                        this.taobaoBill.push(item)
                })
            } else {
                this.taobaoBill.push.apply(this.taobaoBill, data.result)
            }
            if (data.hasNext) {
                await Runtime.evaluate({
                    expression: 'document.querySelectorAll(".tc.mt20 a")[1].click()'
                })
            } else {
                var { result } = await Runtime.evaluate({
                    expression: 'location.href'
                })
                if (result.value.indexOf('queryType=2') != -1) {
                    var startTime = require('../../../lib/formatDate')(new Date(new Date().getTime() - 15 * 86400 * 1000), 'yyyy-MM-dd')
                    var endTime = require('../../../lib/formatDate')(new Date(), 'yyyy-MM-dd')
                    var url = 'https://pub.alimama.com/manage/effect/overview_orders.htm?pageNo=1&queryType=3&jumpType=0&positionIndex=&startTime=' + startTime + '&endTime=' + endTime
                    logger.debug('[' + __filename + ':' + __line + ']', '抓取' + url)
                    setTimeout(() => {
                        Page.navigate({
                            url
                        })
                    }, 1000)
                } else {
                    logger.debug('[' + __filename + ':' + __line + ']', '获取淘宝订单结束，释放chrome')
                    this.getTaobaoBillResolve(this.taobaoBill)
                    clearTimeout(this.getTaobaoBillTimeout)
                    setTimeout(() => {
                        Page.navigate({
                            url: 'https://www.baidu.com/'
                        })
                    }, 1000)
                }
            }
        }
    })
    Page.loadEventFired(async () => { })
    Promise.all([Network.enable(), Page.enable(), DOM.enable()]).then(async () => {
        logger.debug('[' + __filename + ':' + __line + ']', 'taobao chrome[' + this.host + ':' + this.port + '] connected')
        this.client = client
        this.resolve()
        // screenshot(client)
    }).catch(err => {
        log(err);
        client.close();
    });
}

function cgsResolve(client) {
    // 0: 加载登录页中
    // 1: 登录成功
    var stage = 0;
    const {
        Network,
        Page,
        DOM,
        Runtime,
        Emulation
    } = client;
    var requestIds = []
    Network.requestWillBeSent(obj => {
        if (stage == 0) {
            if (obj.request.url.indexOf('http://125.95.19.22/fsweixin/AuthImage') != -1) {
                requestIds[0] = obj.requestId
            } else if (obj.request.url.indexOf('http://125.95.19.22/fsweixin/UserServlet') != -1) {
                requestIds[1] = obj.requestId
            }
        } else if (stage == 5) {
            if (obj.request.url == 'http://125.95.19.22/fsweixin/QueryCarServlet') {
                requestIds[2] = obj.requestId
            }
        }
        // log(obj.request.url);
    });
    Network.loadingFinished(async obj => {
        if (stage == 0) {
            if (obj.requestId == requestIds[0]) {
                var result = await Network.getResponseBody({
                    requestId: obj.requestId
                });
                if (result.body == '') {
                    await Runtime.evaluate({
                        expression: 'reloadImg()'
                    })
                    return
                }
                require('fs').writeFile('/tmp/cgs.jpg', new Buffer(result.body, 'base64'), 'base64', async err => {
                    if (err) {
                        log(err);
                        return
                    }
                })
                if (!ocrMng.aipOcr) {
                    return
                }
                result = await ocrMng.aipOcr.generalBasic(result.body)
                // result = await aipOcr.accurateBasic(result.body)
                var validateCode = result.words_result[0].words.replace(/[\r\n\s]/gm, '')
                if (validateCode.length != 4) {
                    await Runtime.evaluate({
                        expression: 'reloadImg()'
                    })
                    return
                }
                result = await DOM.getDocument();
                var rootNodeId = result.root.nodeId
                await Runtime.evaluate({
                    expression: 'document.querySelectorAll("#username")[0].value="440682198906064373"'
                })
                await Runtime.evaluate({
                    expression: 'document.querySelectorAll("#password")[0].value="123654"'
                })
                await Runtime.evaluate({
                    expression: 'document.querySelectorAll("#validateCode")[0].value="' + validateCode + '"'
                })
                await Runtime.evaluate({
                    expression: 'login()'
                })
            } else if (obj.requestId == requestIds[1]) {
                var result = await Network.getResponseBody({
                    requestId: obj.requestId
                })
                if (result.body == '0') {
                    stage = 1
                } else {
                    setTimeout(() => {
                        Runtime.evaluate({
                            expression: 'reloadImg()'
                        })
                    }, 1000)
                }
            }
        } else if (stage == 5) {
            if (obj.requestId == requestIds[2]) {
                stage++
                await Runtime.evaluate({
                    expression: 'document.getElementsByTagName("a")[13].click()'
                })
            }
        }
    })
    Page.loadEventFired(async () => {
        this.isLoadEventFired = true
        var result = await DOM.getDocument();
        //log(result)
        var rootNodeId = result.root.nodeId
        if (stage == 1) {
            result = await DOM.querySelectorAll({
                nodeId: rootNodeId,
                selector: '#wscgs'
            });
            result = await DOM.getAttributes({
                nodeId: result.nodeIds[0]
            })
            for (var i = 0; i < result.attributes.length; i += 2) {
                if (result.attributes[i] == 'onclick') {
                    stage++
                    await Runtime.evaluate({
                        expression: result.attributes[i + 1]
                    })
                    break
                }
            }
        } else if (stage == 2) {
            stage++
            await Runtime.evaluate({
                expression: 'document.getElementsByTagName("a")[1].click()'
            })
        } else if (stage == 3) {
            stage++
            await Runtime.evaluate({
                expression: 'document.getElementsByTagName("a")[1].click()'
            })
        } else if (stage == 4) {
            stage++
            await Runtime.evaluate({
                expression: 'document.getElementsByTagName("a")[2].click()'
            })
        } else if (stage == 6) {
            result = await DOM.getOuterHTML({
                nodeId: rootNodeId
            })
            if (result.outerHTML.indexOf('没有查询到未处理的交通违法记录!') != -1) {
                log('没有查询到未处理的交通违法记录!')
            }
            this.busy = false
        }
    });
    Promise.all([Network.enable(), Page.enable(), DOM.enable()]).then(async () => {
        log('chrome[' + this.host + ':' + this.port + '] connected')
        this.client = client
        //this.getHtml = require('./getHtml')
    }).catch(err => {
        log(err);
        client.close();
    });
}

function wechatResolve(client) {
    const {
        Network,
        Page,
        DOM,
        Runtime,
        Emulation
    } = client;
    var qrcodeRequestId;
    Network.requestWillBeSent(obj => {
        //log(obj.request.url)
        if (obj.request.url.indexOf('https://login.weixin.qq.com/qrcode/') != -1)
            qrcodeRequestId = obj.requestId
    })
    Network.loadingFinished(async obj => {
        if (obj.requestId == qrcodeRequestId) {
            var result = await Network.getResponseBody({
                requestId: obj.requestId
            });
            this.qrcode = result.body;
            //require('fs').writeFile('/qrcode.jpg', new Buffer(result.body, 'base64'), 'base64', async err => {
            //	if (err) {
            //		console.log(err);
            //		return
            //	}
            //})
        }
    })
    Promise.all([Network.enable(), Page.enable(), DOM.enable()]).then(async () => {
        log('chrome[' + this.host + ':' + this.port + '] connected')
        this.client = client;
    }).catch(err => {
        log(err);
        client.close();
    });
}

function jdResolve(client) {
    const {
        Network,
        Page,
        DOM,
        Runtime,
        Emulation
    } = client;
    var jdBillRequestId
    var jdCodeRequestId
    Network.requestWillBeSent(obj => {
        if (obj.request.url == 'https://media.jd.com/rest/report/detail/in/page') {
            jdBillRequestId = obj.requestId
        } else if (obj.request.url.indexOf('https://authcode.jd.com/verify/image') != -1) {
            jdCodeRequestId = obj.requestId
        }
    });
    Network.loadingFinished(async obj => {
        if (obj.requestId == jdBillRequestId) {
            var result = await Network.getResponseBody({
                requestId: obj.requestId
            })
            result = JSON.parse(result.body)
            this.jdBill.push.apply(this.jdBill, result.data)
            if (result.pagination.pageNum > 1) {
                logger.warn('[' + __filename + ':' + __line + ']', '京东页数多于1')
                require('../pushMng').push('京东订单页数多于1')
            }
            logger.debug('[' + __filename + ':' + __line + ']', '获取京东订单结束，释放chrome')
            this.getJdBillResolve(this.jdBill)
        } else if (obj.requestId == jdCodeRequestId) {
            log('需要输入京东验证码')
            var result = await Network.getResponseBody({
                requestId: obj.requestId
            })
            this.code = result.body
            this.codeRequestId = obj.requestId
            this.codeText = ''
        }
    })
    Page.loadEventFired(async () => { })
    Promise.all([Network.enable(), Page.enable(), DOM.enable()]).then(async () => {
        logger.debug('[' + __filename + ':' + __line + ']', 'jd chrome[' + this.host + ':' + this.port + '] connected')
        this.client = client
        this.resolve()
        // screenshot(client)
    }).catch(err => {
        log(err);
        client.close();
    });
}

module.exports = ChromeMng